Code
%%capture
from google.colab import drive
drive.mount('/content/drive')Re-rethinking the causes of deforestation: does the theory evolve? by Desra Arriyadi
This section sets up the Python environment by importing essential libraries like pandas, numpy, sklearn, and other libraries.
Packages like wbgapi (for accessing World Bank data) and geoviews (for geospatial visualization) are installed to handle data processing and visualization tasks.
import wbgapi as wb
import pandas as pd
import numpy as np
import geopandas as gpd
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import seaborn as sns
import altair as alt
import requests
import folium
from folium import Choropleth
import holoviews as hv
import hvplot.pandas
from vega_datasets import data
# Models
from sklearn.ensemble import RandomForestRegressor
# Model selection
from sklearn.model_selection import train_test_split, GridSearchCV, cross_val_score
# Pre-Processing
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
# Pipelines
from sklearn.pipeline import make_pipeline
# Metrics
from sklearn.metrics import recall_score, r2_score
pd.set_option('display.max_columns',500)
pd.set_option('display.max_rows', 100)
hv.extension("bokeh")Filter out non-country entities (like regions or continents) from the World Bank data. The allCountry DataFrame initially includes all entities, but only rows with valid country-level data are retained by dropping NaN values and extracting the country id into allCountryList.
Data is retrieved for specific variables relevant to deforestation, such as forest area, agricultural land, economy, and other variables.
allVariables =['AG.LND.AGRI.K2',
'AG.LND.FRST.ZS',
'AG.LND.AGRI.ZS',
'AG.LND.ARBL.HA',
'AG.LND.CROP.ZS',
'AG.LND.FRST.K2',
'AG.LND.TOTL.UR.K2',
'AG.PRD.CREL.MT',
'AG.PRD.CROP.XD',
'EG.USE.COMM.FO.ZS',
'EG.USE.PCAP.KG.OE',
'EN.POP.DNST',
'GE.EST',
'NV.AGR.TOTL.ZS',
'NY.ADJ.DFOR.CD',
'NY.GDP.FRST.RT.ZS',
'NY.GDP.MKTP.KD.ZG',
'PV.EST',
'RQ.EST',
'SE.ADT.LITR.ZS',
'SE.PRM.ENRR',
'SE.SEC.ENRR',
'SH.STA.MALN.ZS',
'SI.POV.DDAY',
'SI.POV.GINI',
'SL.AGR.0714.ZS',
'SL.AGR.EMPL.ZS',
'SL.EMP.SELF.ZS',
'SL.TLF.TOTL.IN',
'SN.ITK.DEFC.ZS',
'SP.POP.GROW',
'SP.POP.TOTL',
'SP.RUR.TOTL',
'SP.RUR.TOTL.ZG',
'SP.RUR.TOTL.ZS',
'SP.URB.GROW',
'SP.URB.TOTL.IN.ZS',
'TM.VAL.AGRI.ZS.UN',
'TM.VAL.MRCH.XD.WD',
'TX.VAL.AGRI.ZS.UN',
'VC.IDP.TOCV',
'AG.CON.FERT.PT.ZS',
'AG.LND.TOTL.RU.K2',
'BG.GSR.NFSV.GD.ZS',
'BM.GSR.FCTY.CD',
'BM.GSR.TRVL.ZS',
'BX.GSR.GNFS.CD',
'CC.EST',
'CM.MKT.LCAP.CD',
'DT.DOD.DECT.CD',
'DT.DOD.DIMF.CD',
'DT.TDS.DECT.CD',
'DT.TDS.MLAT.CD',
'FB.CBK.BRWR.P3',
'FM.AST.DOMS.CN',
'FM.AST.NFRG.CN',
'FP.CPI.TOTL',
'GC.TAX.EXPT.CN',
'GC.TAX.GSRV.CN',
'GC.TAX.INTT.CN',
'GC.XPN.TRFT.CN',
'HD.HCI.OVRL',
'IS.RRS.TOTL.KM',
'LP.EXP.DURS.MD',
'NY.GDP.MKTP.CD'
]This function process_wb_variables retrieves and processes data from the World Bank API for a list of variables, countries, and years.
Purpose: Fetch data for specified variables and merge into a single DataFrame for analysis. Process includes data for each variable is fetched and cleaned (resetting index, renaming columns, filtering by countries, and restructuring into long format). Years are standardized as integers. Each variable’s data is stored in a list. All variables’ data are merged into a single DataFrame by country, year, and ID. Error Handling: Logs errors for individual variables and raises an exception if no data is successfully processed. Output: Returns a comprehensive DataFrame (wbData) containing aligned data for all variables, countries, and years.
# Note: range start year to end year-1
def process_wb_variables(variables, allCountryList, time_range=range(2000, 2024)):
# List to store processed dataframes
processed_dfs = []
# Process each variable
for variable in variables:
try:
# Fetch data
dfGetData = wb.data.DataFrame(variable, time=time_range, labels=True)
# Reset the index to make 'economy' and 'economy_label' as columns
dfGetData = dfGetData.reset_index()
# Rename the columns
dfGetData = dfGetData.rename(columns={
'economy': 'ID',
dfGetData.columns[1]: 'Country'
})
# Filter countries
dfGetData = dfGetData[dfGetData['ID'].isin(allCountryList)]
# Melt the DataFrame
melted_df = dfGetData.melt(
id_vars=['ID', 'Country'],
var_name='year',
value_name=variable # Use variable code as value column name
)
# Convert year to integer
melted_df['year'] = melted_df['year'].astype(str).str.replace('YR', '').astype(int)
# Sort and add to list
melted_df = melted_df.sort_values(['ID', 'year'])
processed_dfs.append(melted_df)
#print(f"Processed {variable} successfully")
except Exception as e:
print(f"Error processing {variable}: {e}")
# Merge all processed dataframes
if processed_dfs:
# Merge on ID, Country, and year
merged_df = processed_dfs[0]
for dfGetData in processed_dfs[1:]:
merged_df = pd.merge(merged_df, dfGetData, on=['ID', 'Country', 'year'], how='outer')
return merged_df
else:
raise ValueError("No variables could be processed")
# Process all variables
wbData = process_wb_variables(allVariables, allCountryList)| ID | Country | year | AG.LND.AGRI.K2 | AG.LND.FRST.ZS | AG.LND.AGRI.ZS | AG.LND.ARBL.HA | AG.LND.CROP.ZS | AG.LND.FRST.K2 | AG.LND.TOTL.UR.K2 | AG.PRD.CREL.MT | AG.PRD.CROP.XD | EG.USE.COMM.FO.ZS | EG.USE.PCAP.KG.OE | EN.POP.DNST | GE.EST | NV.AGR.TOTL.ZS | NY.ADJ.DFOR.CD | NY.GDP.FRST.RT.ZS | NY.GDP.MKTP.KD.ZG | PV.EST | RQ.EST | SE.ADT.LITR.ZS | SE.PRM.ENRR | SE.SEC.ENRR | SH.STA.MALN.ZS | SI.POV.DDAY | SI.POV.GINI | SL.AGR.0714.ZS | SL.AGR.EMPL.ZS | SL.EMP.SELF.ZS | SL.TLF.TOTL.IN | SN.ITK.DEFC.ZS | SP.POP.GROW | SP.POP.TOTL | SP.RUR.TOTL | SP.RUR.TOTL.ZG | SP.RUR.TOTL.ZS | SP.URB.GROW | SP.URB.TOTL.IN.ZS | TM.VAL.AGRI.ZS.UN | TM.VAL.MRCH.XD.WD | TX.VAL.AGRI.ZS.UN | VC.IDP.TOCV | AG.CON.FERT.PT.ZS | AG.LND.TOTL.RU.K2 | BG.GSR.NFSV.GD.ZS | BM.GSR.FCTY.CD | BM.GSR.TRVL.ZS | BX.GSR.GNFS.CD | CC.EST | CM.MKT.LCAP.CD | DT.DOD.DECT.CD | DT.DOD.DIMF.CD | DT.TDS.DECT.CD | DT.TDS.MLAT.CD | FB.CBK.BRWR.P3 | FM.AST.DOMS.CN | FM.AST.NFRG.CN | FP.CPI.TOTL | GC.TAX.EXPT.CN | GC.TAX.GSRV.CN | GC.TAX.INTT.CN | GC.XPN.TRFT.CN | HD.HCI.OVRL | IS.RRS.TOTL.KM | LP.EXP.DURS.MD | NY.GDP.MKTP.CD | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ABW | Aruba | 2000 | 20.0 | 2.3 | 11.1 | 2000.0 | NaN | 4.2 | 87.4 | NaN | NaN | NaN | NaN | 503.3 | NaN | 0.0 | 13173.8 | 0.0 | 7.6 | NaN | NaN | 97.0 | 108.3 | 93.8 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.0 | 90588.0 | 48268.0 | 1.8 | 53.3 | 0.2 | 46.7 | 2.9 | 206.5 | 0.7 | NaN | NaN | 94.8 | 119.0 | 77016759.8 | 22.6 | 1.815620e+09 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.478961e+09 | 5.541720e+08 | 72.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.873453e+09 |
| 1 | ABW | Aruba | 2001 | 20.0 | 2.3 | 11.1 | 2000.0 | NaN | 4.2 | NaN | NaN | NaN | NaN | NaN | 508.0 | NaN | 0.0 | 13673.8 | 0.0 | 4.2 | NaN | NaN | NaN | 110.9 | 95.3 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0.9 | 91439.0 | 49067.0 | 1.6 | 53.7 | 0.1 | 46.3 | 2.5 | 189.7 | 0.5 | NaN | NaN | NaN | 128.6 | 107083798.9 | 21.9 | 2.018207e+09 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.540655e+09 | 7.006010e+08 | 74.1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.896457e+09 |
| 2 | ABW | Aruba | 2002 | 20.0 | 2.3 | 11.1 | 2000.0 | NaN | 4.2 | NaN | NaN | NaN | NaN | NaN | 511.5 | NaN | 0.0 | 12759.1 | 0.0 | -0.9 | NaN | NaN | NaN | 115.3 | 100.3 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0.7 | 92074.0 | 49746.0 | 1.4 | 54.0 | -0.1 | 46.0 | 2.5 | 161.3 | 1.0 | NaN | NaN | NaN | 93.7 | 167910614.5 | 26.0 | 1.448782e+09 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.706137e+09 | 7.469060e+08 | 76.6 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.961844e+09 |
| 3 | ABW | Aruba | 2003 | 20.0 | 2.3 | 11.1 | 2000.0 | NaN | 4.2 | NaN | NaN | NaN | NaN | NaN | 517.4 | NaN | 0.0 | 14148.0 | 0.0 | 1.1 | NaN | NaN | NaN | 113.9 | 99.4 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.1 | 93128.0 | 50656.0 | 1.8 | 54.4 | 0.3 | 45.6 | 2.7 | 191.7 | 1.2 | NaN | NaN | NaN | 114.2 | 85882681.6 | 25.8 | 1.766140e+09 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.969561e+09 | 7.009150e+08 | 79.4 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 2.044112e+09 |
| 4 | ABW | Aruba | 2004 | 20.0 | 2.3 | 11.1 | 2000.0 | NaN | 4.2 | NaN | NaN | NaN | NaN | NaN | 528.5 | 1.3 | 0.0 | 15276.3 | 0.0 | 7.3 | 1.0 | 0.8 | NaN | 116.2 | 97.2 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 2.1 | 95138.0 | 52098.0 | 2.8 | 54.8 | 1.3 | 45.2 | 2.8 | 287.0 | 1.2 | NaN | NaN | NaN | 84.2 | 109927374.3 | 33.8 | 4.687899e+09 | 1.2 | NaN | NaN | NaN | NaN | NaN | NaN | 2.061564e+09 | 7.227750e+08 | 81.4 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 2.254831e+09 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 5059 | ZWE | Zimbabwe | 2019 | 162000.0 | 45.2 | 39.5 | 4000000.0 | 0.1 | 174906.5 | NaN | 1026006.4 | 104.3 | NaN | NaN | 39.5 | -1.3 | 9.8 | 435782762.1 | 2.0 | -6.3 | -0.9 | -1.5 | 93.2 | 97.5 | NaN | 9.7 | 39.8 | 50.3 | NaN | 62.4 | 70.9 | 5772798.0 | 39.4 | 1.6 | 15271368.0 | 10352460.0 | 1.6 | 67.8 | 1.6 | 32.2 | 0.4 | 79.6 | 2.2 | NaN | 623.5 | NaN | 5.9 | 354325147.1 | 22.4 | 5.266937e+09 | -1.3 | NaN | 1.224936e+10 | 4.681985e+08 | 1.597240e+09 | 16177509.3 | 85.1 | 2.766927e+10 | -4.066235e+10 | 414.7 | NaN | NaN | NaN | NaN | NaN | 3120.0 | NaN | 2.571741e+10 |
| 5060 | ZWE | Zimbabwe | 2020 | 162000.0 | 45.1 | 39.8 | 4000000.0 | 0.2 | 174445.8 | NaN | 1660964.0 | 127.8 | NaN | NaN | 40.1 | -1.3 | 8.8 | 487068344.4 | 2.3 | -7.8 | -1.1 | -1.4 | NaN | 97.4 | NaN | NaN | NaN | NaN | NaN | 58.8 | 67.8 | 5842807.0 | 39.5 | 1.7 | 15526888.0 | 10520709.0 | 1.6 | 67.8 | 1.8 | 32.2 | 0.3 | 82.6 | 1.7 | NaN | 212.5 | NaN | 4.1 | 480586954.8 | 17.6 | 5.263295e+09 | -1.3 | NaN | 1.274203e+10 | 4.876475e+08 | 9.846859e+08 | 9135529.1 | 54.1 | 1.066966e+11 | -3.353351e+11 | 2725.3 | NaN | NaN | NaN | NaN | 0.5 | 3120.0 | NaN | 2.686794e+10 |
| 5061 | ZWE | Zimbabwe | 2021 | 162000.0 | 45.0 | 39.4 | 4000000.0 | 0.2 | 173985.1 | NaN | 2043436.4 | 130.0 | NaN | NaN | 40.8 | -1.3 | 8.8 | 516326002.5 | 1.8 | 8.5 | -1.0 | -1.4 | NaN | 96.0 | NaN | NaN | NaN | NaN | NaN | 53.6 | 64.2 | 6005429.0 | 38.9 | 1.7 | 15797210.0 | 10694237.0 | 1.6 | 67.7 | 1.9 | 32.3 | 0.3 | 118.8 | 2.2 | NaN | 212.5 | NaN | 4.3 | 662301359.7 | 12.8 | 6.574804e+09 | -1.3 | NaN | 1.381758e+10 | 1.422011e+09 | 6.074121e+08 | 20165936.9 | 61.5 | 3.402869e+11 | -3.841839e+11 | 5411.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 2.724052e+10 |
| 5062 | ZWE | Zimbabwe | 2022 | NaN | 44.9 | 39.5 | NaN | 0.2 | 173524.4 | NaN | 1887719.5 | 123.5 | NaN | NaN | 41.5 | -1.3 | 7.2 | NaN | NaN | 6.1 | -0.9 | -1.4 | 89.8 | 95.8 | NaN | NaN | NaN | NaN | NaN | 52.6 | 63.5 | 6169164.0 | 38.1 | 1.7 | 16069056.0 | 10863485.0 | 1.6 | 67.6 | 2.0 | 32.4 | 0.3 | NaN | 1.3 | NaN | 212.5 | NaN | 5.8 | 630683335.9 | 15.0 | 7.453497e+09 | -1.3 | NaN | 1.382954e+10 | 1.352160e+09 | 4.542304e+08 | 7842276.0 | 68.4 | 1.887873e+12 | -2.301768e+12 | 11076.6 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 3.278975e+10 |
| 5063 | ZWE | Zimbabwe | 2023 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | -1.2 | 4.1 | NaN | NaN | 5.3 | -0.9 | -1.3 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 6320388.0 | NaN | 1.7 | 16340822.0 | 11027277.0 | 1.5 | 67.5 | 2.1 | 32.5 | 0.3 | NaN | 1.2 | NaN | NaN | NaN | 5.8 | 442297465.1 | 17.8 | 7.602718e+09 | -1.3 | NaN | 1.421339e+10 | 1.363159e+09 | 1.161955e+09 | 62317585.3 | 74.5 | 1.666135e+13 | -1.886184e+13 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 3.523137e+10 |
5064 rows × 68 columns
Create a DataFrame codeDescription that maps World Bank variable codes to their human-readable descriptions, making the data easier to interpret. The DataFrame contains two columns: Variable (the code) and Description (its explanation).
The output of this cell is referenced multiple times in subsequent processes to provide clear, descriptive labels for the variables used in the analysis.
| Variable | Description | |
|---|---|---|
| 0 | AG.CON.FERT.PT.ZS | Fertilizer consumption (% of fertilizer produc... |
| 1 | AG.CON.FERT.ZS | Fertilizer consumption (kilograms per hectare ... |
| 2 | AG.LND.AGRI.K2 | Agricultural land (sq. km) |
| 3 | AG.LND.AGRI.ZS | Agricultural land (% of land area) |
| 4 | AG.LND.ARBL.HA | Arable land (hectares) |
| ... | ... | ... |
| 1492 | VC.IDP.TOCV | Internally displaced persons, total displaced ... |
| 1493 | VC.IHR.PSRC.FE.P5 | Intentional homicides, female (per 100,000 fem... |
| 1494 | VC.IHR.PSRC.MA.P5 | Intentional homicides, male (per 100,000 male) |
| 1495 | VC.IHR.PSRC.P5 | Intentional homicides (per 100,000 people) |
| 1496 | 1496 elements |
1497 rows × 2 columns
Reshape the dataset from wide to long format using pd.melt, where variables are listed under a Variable column, and their corresponding values are placed in a Value column. Essential identifiers like ID, Country, and year are retained, while all other columns are melted. The reshaped data is then grouped by ID, Country, and Variable to calculate the average value of each variable across all years, resulting in two DataFrames: wbData_melted for detailed analysis and wbAverageValue for summarizing variable averages by country.
columns_to_keep = ["ID", "Country", "year"]
data_columns = wbData.columns.difference(columns_to_keep)
# Use pd.melt to reshape the data
wbData_melted = pd.melt(
wbData,
id_vars=columns_to_keep,
value_vars=data_columns,
var_name="Variable",
value_name="Value"
)
# Calculate the average Value based on year
wbAverageValue = wbData_melted.groupby(['ID','Country', 'Variable'])['Value'].mean().reset_index()Fetch Country Boundaries: A GeoJSON file containing country boundary data is retrieved from the Natural Earth GeoServer. The requests library is used to fetch the data, and it is converted into a GeoDataFrame (world) using geopandas.
# Get country boundaries from Natural Earth GeoServer
url = "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_110m_admin_0_countries.geojson"
response = requests.get(url, headers={"Accept": "application/json"})
geojson_data = response.json()
world = gpd.GeoDataFrame.from_features(geojson_data["features"])The GeoDataFrame (world) is merged with the previously cleaned World Bank data (wbAverageValue) based on the matching country IDs (WB_A3 from the GeoServer and ID from the cleaned data). This creates a GeoDataFrame (wbDataGeo) that combines spatial and non-spatial data for each country. The merged GeoDataFrame retains only necessary columns: geometry (spatial information for mapping), Country, Variable (World Bank variable), and Value (its average value).
A copy of the merged GeoDataFrame (wbDataGeoCopy) is created and enriched by merging with the codeDescription DataFrame to add human-readable descriptions for each variable. Values are rounded for clearer presentation.
| geometry | Country | Variable | Value | Description | |
|---|---|---|---|---|---|
| 0 | MULTIPOLYGON (((180 -16.06713, 180 -16.55522, ... | Fiji | AG.CON.FERT.PT.ZS | NaN | Fertilizer consumption (% of fertilizer produc... |
| 1 | MULTIPOLYGON (((180 -16.06713, 180 -16.55522, ... | Fiji | AG.LND.AGRI.K2 | 3290.9 | Agricultural land (sq. km) |
| 2 | MULTIPOLYGON (((180 -16.06713, 180 -16.55522, ... | Fiji | AG.LND.AGRI.ZS | 18.0 | Agricultural land (% of land area) |
| 3 | MULTIPOLYGON (((180 -16.06713, 180 -16.55522, ... | Fiji | AG.LND.ARBL.HA | 79263.6 | Arable land (hectares) |
| 4 | MULTIPOLYGON (((180 -16.06713, 180 -16.55522, ... | Fiji | AG.LND.CROP.ZS | 4.2 | Permanent cropland (% of land area) |
| ... | ... | ... | ... | ... | ... |
| 10655 | POLYGON ((30.83385 3.50917, 29.9535 4.1737, 29... | South Sudan | SP.URB.TOTL.IN.ZS | 18.4 | Urban population (% of total population) |
| 10656 | POLYGON ((30.83385 3.50917, 29.9535 4.1737, 29... | South Sudan | TM.VAL.AGRI.ZS.UN | NaN | Agricultural raw materials imports (% of merch... |
| 10657 | POLYGON ((30.83385 3.50917, 29.9535 4.1737, 29... | South Sudan | TM.VAL.MRCH.XD.WD | NaN | Import value index (2015 = 100) |
| 10658 | POLYGON ((30.83385 3.50917, 29.9535 4.1737, 29... | South Sudan | TX.VAL.AGRI.ZS.UN | NaN | Agricultural raw materials exports (% of merch... |
| 10659 | POLYGON ((30.83385 3.50917, 29.9535 4.1737, 29... | South Sudan | VC.IDP.TOCV | 1280461.5 | Internally displaced persons, total displaced ... |
10660 rows × 5 columns
Create an interactive geospatial map using hvplot to visualize World Bank data across countries. The map displays variable values (Value) with color gradients (cmap=‘plasma’) on a dark background (tiles=‘CartoDark’) and allows users to switch between variables using a dropdown menu (groupby=‘Description’). Hover functionality reveals country names and values, and the map is styled with a minimal dark theme for clarity.
# Boundary
x_rangemap = (-180, 180)
y_rangemap = (-90, 90)
# Create map
img = wbDataGeoVis.hvplot(
geo=True,
dynamic=False,
tiles='CartoDark',
frame_width=400,
frame_height=400,
c='Value',
groupby='Description',
cmap='plasma',
hover_cols=['Country', 'Value'],
xlim=x_rangemap,
ylim=y_rangemap
)
hv.renderer('bokeh').theme = 'dark_minimal'
img